package sg.edu.nus.iss.billing.datastore.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import sg.edu.nus.iss.billing.datastore.AbstractFileStorage;

/**
 * Implement the object-to-file/file-to-object storage in way of serialize
 * 
 * @author Wang Dayong
 * 
 */
public class SerializeStorage extends AbstractFileStorage {

	public SerializeStorage(String rootPath) {

		super(rootPath);
	}

	public SerializeStorage(String rootPath, boolean isCacheOn) {

		super(rootPath, isCacheOn);
	}

	@Override
	protected Object loadObjectFromFile(String fileName) throws IOException, ClassNotFoundException {

		ObjectInputStream oos = null;
		try {
			File file = new File(getRealPath(fileName));
			if (!file.exists()) {
				return null;
			}
			if (file.isDirectory()) {
				throw new FileNotFoundException("Wrong Data File format: format is folder");
			}
			oos = new ObjectInputStream(new FileInputStream(file));
			return oos.readObject();
		} catch (FileNotFoundException e) {
			throw e;
		} finally {
			if (oos!=null)
				oos.close();
		}

	}

	@Override
	protected Object loadObjectFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {

		if (bytes==null||bytes.length==0) {
			return null;
		}
		ObjectInputStream oos = null;
		try {
			oos = new ObjectInputStream(new ByteArrayInputStream(bytes));
			return oos.readObject();
		} catch (ClassNotFoundException e) {
			throw e;
		} finally {
			if (oos!=null)
				oos.close();
		}

	}

	@Override
	protected void writeObject2File(String fileName, Object saveObj) throws IOException {

		if (saveObj==null) {
			return;
		}

		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(new File(getRealPath(fileName))));

			oos.writeObject(saveObj);
			oos.flush();
		} finally {
			if (oos!=null) {
				try {
					oos.close();
				} catch (IOException e) {
					throw e;
				}
			}
		}
	}

	@Override
	protected byte[] getBytesFromObject(Object saveObj) throws IOException {

		if (saveObj==null) {
			return null;
		}

		ObjectOutputStream oos = null;
		ByteArrayOutputStream byteout = null;
		try {
			byteout = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(byteout);
			oos.writeObject(saveObj);
			return byteout.toByteArray();
		} finally {
			if (byteout!=null)
				byteout.close();
			if (oos!=null)
				oos.close();
		}
	}

}
